package logica;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;

import excepciones.BandoException;

import value_objects.VoBarco;

public class Bando {
	// Constantes
	public static final String BANDO_VERDE = "Verde";
	public static final String BANDO_ROJO = "Rojo";
	public static final String BANDO_AZUL = "Azul";
	
	private String nombreBando;
	private Hashtable<String, Barco> hashBarcos;
	
	/**
	 * Constructor por defecto
	 */
	public Bando() {
		hashBarcos = new Hashtable<String, Barco>();
		nombreBando = "";
	}
	
	/**
	 * Constructor normal a partir del nombre de bando y la dificultad elegida.
	 * 
	 * @param _nombreBando
	 * @param _dificultad
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws BandoException
	 */
	public Bando (String _nombreBando, Integer _dificultad) throws FileNotFoundException, IOException, BandoException {
		this.hashBarcos  = new Hashtable<String, Barco>();
		this.nombreBando = _nombreBando;
		crearBarcos(_dificultad);
	}

	/**
	 * Crea todos los barcos del bando en base a la dificultad elegida
	 * @param _dificultad
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws BandoException
	 */
	private void crearBarcos(Integer _dificultad) throws FileNotFoundException, IOException, BandoException {
		if ( this.nombreBando.equalsIgnoreCase(BANDO_ROJO)) {
			//Creamos barco Rojo
			this.hashBarcos.put("Rojo1", new Barco("Rojo1", _dificultad));
		} else if ( this.nombreBando.equalsIgnoreCase(BANDO_AZUL)) {
			//Creamos barcos Azules
			this.hashBarcos.put("Azul1", new Barco("Azul1", _dificultad));
			this.hashBarcos.put("Azul2", new Barco("Azul2", _dificultad));
			this.hashBarcos.put("Azul3", new Barco("Azul3", _dificultad));
		} else if ( this.nombreBando.equalsIgnoreCase(BANDO_VERDE) ) {
			//Creamos barco Verde
			this.hashBarcos.put("Verde1", new Barco("Verde1", _dificultad));
		} else {
			throw new BandoException(BandoException.ERROR_BANDO_DESCONOCIDO);
		}
	}
	
	/**
	 * Obtiene la info del bando útil para el cliente.
	 * @return
	 */
	public VoBarco[] obtenerInfoBando() {
		Iterator<Barco> barcos = getBarcos();
		VoBarco[] voBarcos = new VoBarco[hashBarcos.size()];
		int i = 0;
		while(barcos.hasNext()) {
			voBarcos[i] = barcos.next().obtenerInfoBarco();
			i++;
		}
		return voBarcos;
	}

	/**
	 * Devuelve un string conteniendo las propiedades del bando como XML.
	 * @return
	 */
	public String getXML() {
		String datosBando = "<NombreBando>" + getNombreBando() + "</NombreBando>" +
							"<CantBarcos>" + getCantidadBarcos() + "</CantBarcos>" +
							"<Barcos>";
		Iterator<Barco> barcos = getBarcos();//BARCOS
	    while (barcos.hasNext()) {
	    	datosBando = datosBando + barcos.next().getXML(getNombreBando());
	    }
		return datosBando + "</Barcos>";
	}

	/**
	 * Devuelve la cantidad de barcos que tiene en juego este bando
	 * @return
	 */
	public Integer cantidadBarcosEnJuego() {
		Integer retorno = 0;
		Iterator<Barco> barcos = getBarcos();
	    while (barcos.hasNext()) {
	    	if (barcos.next().getVida() > 0) {
	    		retorno++;
	    	}
	    }
		return retorno;
	}
	
	/**
	 * Setea la vida de todos los barcos a cero.
	 */
	public void matarBarcos() {
		Iterator<Barco> barcos = getBarcos();
	    while (barcos.hasNext()) {
	    	barcos.next().setVida(0);
	    }
	}

	/**
	 * Determina si este bando tiene un barco en puerto
	 * @return
	 */
	public boolean tieneBarcoEnPuerto() {
		Boolean tieneEnPuerto = false;
		Iterator<Barco> barcos = getBarcos();
	    while (barcos.hasNext() && !tieneEnPuerto) {
	    	Barco barco = barcos.next();
	    	if (barco.getVida() > 0 && barco.getMovimientoHabilitado()) {
	    		tieneEnPuerto = true;
	    	}
	    }
		return tieneEnPuerto;
	}
	
	// ********************* GETTERS Y SETTERS *********************
	
	public Iterator <Barco> getBarcos() {
		return hashBarcos.values().iterator();
	}
	
	public int getCantidadBarcos() {
		return hashBarcos.size();
	}

	public void setHashBarcos (Hashtable<String, Barco> hashBarcos) {
		this.hashBarcos = hashBarcos;
	}

	public String getNombreBando() {
		return nombreBando;
	}

	public void setNombreBando(String _nombreBando) {
		this.nombreBando = _nombreBando;
	}

	public Barco getBarco(String _nombreBarco) {
		return this.hashBarcos.get(_nombreBarco);
	}
	
	public void addBarco(Barco _barco) {
		this.hashBarcos.put(_barco.getNombre(), _barco);
	}
}
